using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Collections.Generic;
using System.IO;


namespace ScreenManagement
{
    /// <summary>
    /// The main menu screen is the first thing displayed when the game starts up.
    /// </summary>
    class MainMenuScreen : MenuScreen
    {
        private SpriteBatch spriteBatch;

        /// <summary>
        /// TotalGameTime.TotalMilliseconds when the screen is loaded. 
        /// We need this to subtract from so we get an accurate count when tracking time played.
        /// We cannot reset totalgametime.
        /// </summary>
        double startMilliseconds;

        /// <summary>
        /// Load settings on first update
        /// </summary>
        bool settingsLoaded = false;

        #region Initialization

        /// <summary>
        /// Constructor fills in the menu contents.
        /// </summary>
        public MainMenuScreen()
            : base("From the Sea: Awakening")
        {
            // Create our menu entries.
            MenuEntry newGameEntry = new MenuEntry("Begin a New Story");
            MenuEntry loadGameMenuEntry = new MenuEntry("Continue Story");
            MenuEntry optionsMenuEntry = new MenuEntry("Options");
            MenuEntry creditsMenuEntry = new MenuEntry("Credits");
            MenuEntry exitMenuEntry = new MenuEntry("Quit");

            // Hook up menu event handlers.
            newGameEntry.Selected += newGameEntrySelected;
            loadGameMenuEntry.Selected += LoadGameMenuEntrySelected;
            optionsMenuEntry.Selected += OptionsMenuEntrySelected;
            creditsMenuEntry.Selected += CreditsMenuEntrySelected;
            exitMenuEntry.Selected += OnCancel;

            // Add entries to the menu.
            MenuEntries.Add(newGameEntry);
            MenuEntries.Add(loadGameMenuEntry);
            MenuEntries.Add(optionsMenuEntry);
            MenuEntries.Add(creditsMenuEntry);
            MenuEntries.Add(exitMenuEntry);
        }

        public override void LoadContent()
        {
            base.LoadContent();

            // Load font for drawing hint
            spriteBatch = new SpriteBatch(this.ScreenManager.GraphicsDevice);
        }

        #endregion

        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            startMilliseconds = gameTime.TotalGameTime.TotalMilliseconds;

            // Try to load existing settings. Give slight pause, added for testing, just so we can load without having to go through intro screen.
            if (!settingsLoaded && startMilliseconds > 1000)
            {
                if (this.ScreenManager.SaveDevice.IsReady)
                {
                    // Turn on Async if we want
                    this.ScreenManager.SaveDevice.LoadAsync("FromTheSeaPt1_Settings", "_settings",
                        stream =>
                        {
                            using (BinaryReader reader = new BinaryReader(stream))
                            {
                                this.ScreenManager.gameSettings.MusicVolume = (float)reader.ReadDouble();           // Load the music volume
                                this.ScreenManager.gameSettings.SoundEffectVolume = (float)reader.ReadDouble();     // Load the sound volume
                                this.ScreenManager.gameSettings.Inverted = reader.ReadBoolean();            // Load inverted
                            }
                        });
                }
                else
                {
                    MessageBoxScreen confirmExitMessageBox = new MessageBoxScreen(new string[] { "Save device is not ready. Could not load options." }, true, false, true, true);
                    confirmExitMessageBox.Accepted += OnCancel;
                    ScreenManager.AddScreen(confirmExitMessageBox, this.ControllingPlayer.Value);
                }

                settingsLoaded = true;
            }

            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
        }

        public override void Draw(GameTime gameTime)
        {
            base.Draw(gameTime);
        }

        #region Handle Input


        /// <summary>
        /// Event handler for when the Single Player menu entry is selected.
        /// </summary>
        void LoadGameMenuEntrySelected(object sender, PlayerIndexEventArgs e)
        {
            ScreenManager.AddScreen(new LoadGameScreen(), e.PlayerIndex);
        }

        /// <summary>
        /// Event handler for when the options menu is selected.
        /// </summary>
        void OptionsMenuEntrySelected(object sender, PlayerIndexEventArgs e)
        {
            ScreenManager.AddScreen(new OptionsMenuScreen(), e.PlayerIndex);
        }

        void CreditsMenuEntrySelected(object sender, PlayerIndexEventArgs e)
        {
            ScreenManager.AddScreen(new CreditsScreen(), e.PlayerIndex);
        }

        void newGameEntrySelected(object sender, PlayerIndexEventArgs e)
        {
            LoadingScreen.Load(this.ScreenManager, true, e.PlayerIndex, new GameplayScreen(startMilliseconds, null, this.ScreenManager.gameSettings));
        }


        /// <summary>
        /// When the user cancels the main menu, ask if they want to exit the sample.
        /// </summary>
        protected override void OnCancel(PlayerIndex playerIndex)
        {
            MessageBoxScreen confirmExitMessageBox = new MessageBoxScreen(new string[] { "Are you sure you want to exit this game?" }, true, true, true, true);

            confirmExitMessageBox.Accepted += ConfirmExitMessageBoxAccepted;

            ScreenManager.AddScreen(confirmExitMessageBox, playerIndex);
        }


        /// <summary>
        /// Event handler for when the user selects ok on the "are you sure
        /// you want to exit" message box.
        /// </summary>
        void ConfirmExitMessageBoxAccepted(object sender, PlayerIndexEventArgs e)
        {
            ScreenManager.Game.Exit();
        }


        #endregion
    }
}
